using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Controllers;
using xjjxmm.infrastructure.Authorizations;
using XjjXmm.Infrastructure.Configuration;
using XjjXmm.Infrastructure.Constant;
using XjjXmm.Infrastructure.Exceptions;
using xjjxmm.infrastructure.ToolKit;
using XjjXmm.Infrastructure.User;
using System.Reflection;
using xjjxmm.infrastructure.Middleware.RateLimit.RateLimit;
using xjjxmm.infrastructure.Common;

namespace xjjxmm.infrastructure.Middleware.RateLimit;

public class RateLimitMiddleware : IMiddleware
{
    private readonly TokenContext _userContext;
    private static Dictionary<string, RateLimitModel> _dictionary = new Dictionary<string, RateLimitModel>();

    public RateLimitMiddleware(TokenContext userContext)
    {
        _userContext = userContext;
    }

    public async Task InvokeAsync(HttpContext httpContext, RequestDelegate next)
    {
        var controllerActionDescriptor = httpContext
            .GetEndpoint()?
            .Metadata
            .GetMetadata<ControllerActionDescriptor>();

        var ratelimitAttribute = controllerActionDescriptor?.MethodInfo.GetCustomAttribute<RateLimitAttribute>();
        if (ratelimitAttribute == null)
        {
            ratelimitAttribute = controllerActionDescriptor?.ControllerTypeInfo.GetCustomAttribute<RateLimitAttribute>();
        }

        if (ratelimitAttribute == null)
        {
            await next(httpContext);
            return;
        }

        var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);
        //frameConfig?.RateConfigs?.ApiRate
        // RateGroup group = ratelimitAttribute!.group;
        //  if((group & RateGroup.Single) == RateGroup.Single)
        // {
        string groupKey = _userContext.Id;
        if (!_dictionary.ContainsKey(groupKey))
        {
            var permitRate = ratelimitAttribute!.PermitRate;
            var maxPermit = ratelimitAttribute.MaxPermit;

            var config2 = ConfigHelper.GetSection<RateConfig>(CommonConstant.RateConfigKey + ":" + groupKey);
            var config = frameConfig!.RateConfigs.ApiRate;


            permitRate ??= config2?.PermitRate ?? config.PermitRate;
            maxPermit ??= config2?.MaxPermits ?? config.MaxPermits;

            RateLimitModel rateLimit = new RateLimitModel(permitRate.Value, maxPermit.Value);
            _dictionary.Add(groupKey, rateLimit);
        }

        if (!_dictionary[groupKey].Acquire())
        {

            throw new BussinessException("访问数量达到限制,请稍后再试");
        }
        /*}
        else
        {
            var groupKey = "system";
            if (!_dictionary.ContainsKey(groupKey))
            {
                var config = frameConfig!.RateConfigs.SystemRate;
                RateLimit rateLimit = new RateLimit(config.PermitRate, config.MaxPermits, 10);
                _dictionary.Add(groupKey, rateLimit);
            }
        
            if (!_dictionary[groupKey].Acquire())
            {
                throw new BussinessException("访问数量达到限制,请稍后再试");
            }     
        }
        */



        await next(httpContext);
    }
}